import { call as sagaCall, put } from 'redux-saga/effects'
import { message } from 'antd'
import { getNamespace } from '../utils/util'
import { show, hide } from './reducers/loading'

type Options = {
  type?: string
  loading?: boolean
}

type Fn = (...args: any[]) => Promise<ResponseData>

const flag: { [name: string]: any } = {}

export default function* call(fn: Fn, action: Action, options = {}) {
  const { loading = true, type } = options as Options
  const loadingAction = type ? { type } : action
  const name = getNamespace(loadingAction?.type)
  if (loading) {
    if (!flag[name]) {
      flag[name] = 1
    } else {
      flag[name]++
    }
    yield put(show(loadingAction))
  }
  try {
    const response: ResponseData = yield sagaCall(fn, action.payload)
    return response
  } catch (error: any) {
    message.error(error?.message)
  } finally {
    if (loading) {
      flag[name]--
      if (flag[name] === 0) {
        yield put(hide(loadingAction))
      }
    }
  }
}
